home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / docs / ippon / ver / 010 / enemy.c next >
C/C++ Source or Header  |  2000-07-07  |  5KB  |  243 lines

  1. /* enemy.c */
  2.  
  3. #include <stdio.h>
  4. #include <xsp2lib.h>
  5.  
  6. #include "main.h"
  7. #include "player.h"
  8. #include "shot.h"
  9. #include "enemy.h"
  10.  
  11. #define ENEMY_MAX    32    /* 敵最大数 */
  12.  
  13. static ENEMY enemy[ENEMY_MAX];    /* ワーク */
  14. static ENEMY *enemy_top,    /* 使用中のワークのリスト */
  15.  *enemy_null_top,        /* 空のワークのリスト */
  16.  *enemy_end;            /* 使用中ワークのリストの末尾 */
  17.  
  18.  
  19. /* 関数プロトタイプ宣言 */
  20. void EnemyAllocA (ENEMY *);
  21. int EnemyMoveA (ENEMY *);
  22. void EnemyAllocB (ENEMY *);
  23. int EnemyMoveB (ENEMY *);
  24.  
  25.  
  26. /* 初期化関数へのポインタの配列 */
  27. typedef void (*enemy_alloc) (ENEMY *);
  28. enemy_alloc EnemyAllocFunc[] =
  29. {
  30.     EnemyAllocA,
  31.     EnemyAllocB,
  32. };
  33.  
  34. /* 移動関数へのポインタの配列 */
  35. typedef int (*enemy_move) (ENEMY *);
  36. enemy_move EnemyMoveFunc[] =
  37. {
  38.     EnemyMoveA,
  39.     EnemyMoveB,
  40. };
  41.  
  42.  
  43. /* タイプAの敵の初期化ルーチン */
  44. void EnemyAllocA (ENEMY * p)
  45. {
  46.     p->pt = obj_zako02 + 15;
  47.     p->info = 0x0700 | PRIORITY_ZAKO;    /* 数値を決めうちして入れるのはよくない */
  48.     p->hit_sx = 12;        /* 自機ショットに対する当たり判定 */
  49.     p->hit_sy = 12;
  50.     p->hp = 1;        /* 耐久力 */
  51.     p->damage = 0;
  52. }
  53.  
  54. /* タイプAの敵の移動ルーチン */
  55. /* 返り値:非0なら消去 */
  56. int EnemyMoveA (ENEMY * p)
  57. {
  58.     /* 敵をくるくる回すアニメーション */
  59.     p->pt--;
  60.     if (p->pt < obj_zako02)
  61.         p->pt = obj_zako02 + 15;
  62.  
  63.     /* X座標を自機に近づける */
  64.     if (p->lx > player->lx)
  65.         p->lx -= 32768;
  66.     else
  67.         p->lx += 32768;
  68.  
  69.     p->ly += 2 * 65536;
  70.  
  71.     /* 上位ワード(固定整数部)だけ取り出す */
  72.     p->x = p->lx >> 16;
  73.     p->y = p->ly >> 16;
  74.  
  75.     if (p->y > 256 + 32)
  76.         return (-1);    /* Y座標が 256+32 以上なら消去 */
  77.  
  78.     /* もし前回ダメージを受けたなら */
  79.     if (p->damage) {
  80.         p->hp -= p->damage;
  81.         p->damage = 0;
  82.         if (p->hp <= 0)
  83.             return (-1);    /* 耐久力が0以下なら消去 */
  84.     }
  85.     xobj_set_st (p);    /* 表示 */
  86.  
  87.     return (0);
  88. }
  89.  
  90.  
  91. /* タイプBの敵の初期化ルーチン */
  92. void EnemyAllocB (ENEMY * p)
  93. {
  94.     p->pt = obj_zako02;
  95.     p->info = 0x0800 | PRIORITY_ZAKO;    /* 数値を決めうちして入れるのはよくない */
  96.     p->hit_sx = 12;        /* 自機ショットに対する当たり判定 */
  97.     p->hit_sy = 12;
  98.     p->hp = 2;        /* 耐久力 */
  99.     p->damage = 0;
  100. }
  101.  
  102. /* タイプBの敵の移動ルーチン */
  103. /* 返り値:非0なら消去 */
  104. int EnemyMoveB (ENEMY * p)
  105. {
  106.     /* 敵をくるくる回すアニメーション */
  107.     p->pt++;
  108.     if (p->pt > obj_zako02 + 15)
  109.         p->pt = obj_zako02;
  110.  
  111.  
  112.     /* X座標を自機に近づける */
  113.     if (p->lx > player->lx)
  114.         p->lx -= 32768;
  115.     else
  116.         p->lx += 32768;
  117.  
  118.     p->ly += 2 * 65536;
  119.  
  120.     /* 上位ワード(固定整数部)だけ取り出す */
  121.     p->x = p->lx >> 16;
  122.     p->y = p->ly >> 16;
  123.  
  124.     if (p->y > 256 + 32)
  125.         return (-1);    /* Y座標が 256+32 以上なら消去 */
  126.  
  127.     /* もし前回ダメージを受けたなら */
  128.     if (p->damage) {
  129.         p->hp -= p->damage;
  130.         p->damage = 0;
  131.         if (p->hp <= 0)
  132.             return (-1);    /* 耐久力が0以下なら消去 */
  133.     }
  134.     xobj_set_st (p);    /* 表示 */
  135.     return (0);
  136. }
  137.  
  138.  
  139.  
  140. /* ゲーム開始時に呼ばれる */
  141. void EnemyInit (void)
  142. {
  143.     int i;
  144.  
  145.     /* リストをつなげる */
  146.     enemy_top = NULL;
  147.     enemy_end = NULL;
  148.     enemy_null_top = enemy;
  149.     for (i = 0; i < ENEMY_MAX; i++)
  150.         enemy[i].next = &enemy[i + 1];
  151.  
  152.     enemy[ENEMY_MAX - 1].next = NULL;
  153. }
  154.  
  155.  
  156.  
  157. /* 敵出現時に呼ばれる */
  158. void EnemyAlloc (short type, signed short x, signed short y)
  159. {
  160.     ENEMY *p;
  161.  
  162.     if (enemy_null_top == NULL)
  163.         return;        /* 空きのワークがない(キャラクターオーバー) */
  164.  
  165.     /* リストの末尾に新しいノードを追加(他とは違うので注意) */
  166.     p = enemy_null_top;
  167.     enemy_null_top = p->next;
  168.     if (enemy_top == NULL)
  169.         enemy_top = p;
  170.     else
  171.         enemy_end->next = p;
  172.     p->next = NULL;
  173.     enemy_end = p;
  174.  
  175.     p->type = type;
  176.     p->lx = x << 16;
  177.     p->ly = y << 16;
  178.  
  179.     /* 関数へのポインタを使って分岐 */
  180.     /* type が 0 なら EnemyAllocA() が、1 なら EnemyAllocB() が実行される */
  181.     EnemyAllocFunc[p->type] (p);
  182.  
  183.     return;
  184. }
  185.  
  186.  
  187.  
  188. /* 垂直同期ごとに呼ばれる */
  189. void EnemyMove (void)
  190. {
  191.     ENEMY *p, *q;
  192.  
  193.     p = enemy_top;        /* 現在注目しているワーク */
  194.     q = NULL;        /* 1つ前のワーク(ワーク削除時に必要) */
  195.     while (p != NULL) {
  196.         /* 敵キャラの移動ルーチン */
  197.  
  198.         /* 関数へのポインタを使って分岐 */
  199.         /* type が 0 なら EnemyMoveA() が、1 なら EnemyMoveB() が実行される */
  200.  
  201.         if (EnemyMoveFunc[p->type] (p)) {    /* 返り値が非0なら消去 */
  202.             if (q == NULL) {    /* リストの一番最初を削除 */
  203.                 enemy_top = p->next;
  204.                 p->next = enemy_null_top;
  205.                 enemy_null_top = p;
  206.                 q = NULL;
  207.                 p = enemy_top;
  208.             } else {
  209.                 if (p == enemy_end) {    /* リストの一番最後を削除 */
  210.                     q->next = NULL;
  211.                     enemy_end = q;
  212.                     p->next = enemy_null_top;
  213.                     enemy_null_top = p;
  214.                     p = q->next;
  215.                 } else {
  216.                     q->next = p->next;
  217.                     p->next = enemy_null_top;
  218.                     enemy_null_top = p;
  219.                     p = q->next;
  220.                 }
  221.             }
  222.         } else {
  223.             /* 敵キャラを消去しない場合 */
  224.             SHOT *p2 = shot_top;    /* 現在注目しているショットのワーク */
  225.  
  226.             /* ショットとの当たり判定 */
  227.             while (p2 != NULL) {
  228.                 if ((p->x - p->hit_sx <= p2->x + p2->hit_x)
  229.                     && (p->x + p->hit_sx >= p2->x - p2->hit_x)
  230.                     && (p->y - p->hit_sy <= p2->y + p2->hit_y)
  231.                     && (p->y + p->hit_sy >= p2->y - p2->hit_y)) {
  232.                     /* ショットが当たった */
  233.                     p->damage++;    /* 敵キャラにダメージを与える */
  234.                     p2->damage = !0;    /* 自機ショットに当たった事を知らせる */
  235.                 }
  236.                 p2 = p2->next;
  237.             }
  238.             q = p;
  239.             p = p->next;
  240.         }
  241.     }
  242. }
  243.